##
# Author: Samuel Abels <http://debain.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
##
import string, os
from config          import c as cfg
from xml.dom.minidom import parseString
from Workflow        import Workflow
from SpiffWarehouse  import Store

class WorkflowDB(object):
    def __init__(self, file):
        """
        Creates a new instance of WorkflowDB. The given path is scanned
        for workflows, and any workflows are pre-loaded.
        """
        dirname = os.path.dirname(file)
        if not os.path.isdir(dirname):
            try:
                os.makedirs(dirname)
            except:
                pass
        self.store = Store(file)


    def workflow_exists(self, name, revision = None):
        """
        Returns True if a workflow with the given name exists.
        Returns False otherwise.
        """
        return self.store.exists('workflow/' + name, revision, deleted = True)


    def find_workflow(self, str = '', include_deleted = False):
        """
        Returns all workflows that match the given string. '%' wildcards
        are allowed.
        """
        return [Workflow.from_blob(b)
                for b in self.store.find(content = str,
                                         deleted = include_deleted)]


    def get_workflow(self, name, revision = None):
        """
        Returns the workflow with the given name, or None if no such workflow
        exists.
        """
        name = 'workflow/' + name
        blob = self.store.get(name, None, revision, deleted = True)
        if not blob:
            return None
        return Workflow.from_blob(blob)


    def get_workflow_from_id(self, id):
        """
        Returns the workflow with the given id, or None if no such workflow
        exists.
        """
        return Workflow.from_blob(self.store.get_from_id(id))


    def delete_workflow(self, workflow):
        """
        Deletes the given workflow.
        """
        self.store.delete(workflow.blob)
        self.store.commit()


    def save_workflow(self, workflow):
        """
        Saves the given workflow. It is an error if a workflow with the
        given name already exists.
        """
        # Check for duplicates.
        if self.workflow_exists(workflow.get_name()):
            existing = self.get_workflow(workflow.get_name())
            if workflow.blob.id != existing.blob.id:
                raise Exception('Duplicate workflow name.')

        # Save.
        self.store.add('workflow/' + workflow.get_name(), workflow.blob)
        self.store.commit()
